package com.psiqueware.alheli.manager;

import com.psiqueware.alheli.basico.BaseObjectInterface;
import com.psiqueware.alheli.dao.BaseDAOFactory;
import com.psiqueware.alheli.dao.EnlaceTransaccional;
import com.psiqueware.alheli.dao.TipoDAO;
import com.psiqueware.alheli.exception.NullArgumentException;

import java.math.BigInteger;
import java.util.List;

/**
 * Encargado de negocio con funcionalidades de servicio b&aacute;sico.
 * <br/>Paquete Original: com.psiqueware.basico
 * <br/>Nombre  Original: BaseManager
 * <br/><a href="BaseManager.java.html"><i>Ver C&oacute;digo Fuente</i> </a>
 *
 * @author <a href="mailto:AngelElectrico@PsiqueWare.com">Angel El&eacute;ctrico</a>
 * @version Revision: 1.0 07/02/06
 */
public abstract class BaseManager implements BaseManagerInterface
{

    /**
     * Tama&ntilde;o de la semilla aleatoria devuelta por el manager.
     */
    private static final int TAMANIO_ALEATORIO = 16;

    /**
     * Construye una BaseManager.
     * <p>No requiere argumentos.</p>
     */
    public BaseManager()
    {
    }

    /**
     * Busca un {@link BaseObjectInterface} en una Lista de estos en base a un idBuscado
     *
     * @param idBuscado id del BaseObject que se busca.
     * @param lista     {@link List} donde se esta buscando el objeto.
     *
     * @return BaseObject del id correspondiente; <code>null</code> si no lo encuetra o alguno de los par&aacute;metros es <code>null</code>.
     */
    protected BaseObjectInterface buscaObjetoListaAnidada(final Long idBuscado, final List<? extends BaseObjectInterface> lista)
    {
        BaseObjectInterface salida = null;

        if (null != lista && null != idBuscado)
        {
            for (BaseObjectInterface o : lista)
            {
                if (idBuscado.equals(o.getId()))
                {
                    salida = o;
                    break;
                }
            }
        }
        return salida;
    }


    //--- Creaci&oacute;n aleatoria de n&uacute;meros de 16 d&iacute;gitos.
    // for details on magic numbers see Knuth - Seminumerical Algorithms p.155
    private static final BigInteger PRE_A = new BigInteger("9578627463263421");

    private static final BigInteger PRE_C = new BigInteger("2113248654051873");

    private static final BigInteger PRE_M = new BigInteger("10000000000000000");

    protected static String semillaAleatoria(Long semilla)
    {
        if (null == semilla)
            throw new NullArgumentException("<error>El argumento 'semilla' no puede ser NULL.</error>");
        if (0 > semilla)
            throw new IllegalArgumentException("<error>El argumento 'semilla' no puede ser menor a cero.</error>");

        String in = "" + semilla;
        BigInteger x = new BigInteger(in);
        StringBuilder sb = new StringBuilder(x.multiply(PRE_A).add(PRE_C).mod(PRE_M).toString());
        while (sb.length() < TAMANIO_ALEATORIO)
            sb.insert(0, String.valueOf(Math.random()).substring(0, 1)); // supply leading numbers to small numbers.

        return sb.toString();
    }


    /**
     * Devuelve un nuevo enlace transaccional para el tipo DAO elegido.
     *
     * @return EnlaceTransaccional dependiendo de TipoDAO.
     */
    public EnlaceTransaccional nuevoEnlace()
    {
        return BaseDAOFactory.nuevoEnlace();
    }

    /**
     * Devuelve un nuevo enlace transaccional para el tipo DAO elegido.
     *
     * @return EnlaceTransaccional dependiendo de TipoDAO.
     */
    public EnlaceTransaccional nuevoEnlace(final TipoDAO tipoDAO)
    {
        return BaseDAOFactory.nuevoEnlace();
    }
}
